package com.jas.logic;

import java.util.TreeMap;

import com.jas.common.Language;
import com.jas.common.Utilities;
import com.jas.logic.Logic.KeywordType;

public class KeywordAndParameterParser {

	private TreeMap<String, KeywordType> mappingOfStringsToKeywords;
	private String tokenizerDelimiterRegex;

	//@author a0118677r
	public KeywordAndParameterParser() {
		mappingOfStringsToKeywords = new TreeMap<String, KeywordType>();
		updateLanguage();
	}

	//@author a0118677r
	protected void updateLanguage() {
		mappingOfStringsToKeywords.put(Language.getString("KEYWORD_BY"),
				KeywordType.END);
		mappingOfStringsToKeywords.put(Language.getString("KEYWORD_TO"),
				KeywordType.END);
		mappingOfStringsToKeywords.put(Language.getString("KEYWORD_FROM"),
				KeywordType.START);
		mappingOfStringsToKeywords.put(
				Language.getString("KEYWORD_DESCRIPTION"),
				KeywordType.DESCRIPTION);
		mappingOfStringsToKeywords.put(Language.getString("KEYWORD_START"),
				KeywordType.START);
		mappingOfStringsToKeywords.put(Language.getString("KEYWORD_END"),
				KeywordType.END);
		mappingOfStringsToKeywords.put(Language.getString("KEYWORD_SET"),
				KeywordType.SET);

		tokenizerDelimiterRegex = "\\b" + Language.getString("KEYWORD_BY")
				+ "\\b|" + "\\b" + Language.getString("KEYWORD_TO") + "\\b|"
				+ "\\b" + Language.getString("KEYWORD_FROM") + "\\b|" + "\\b"
				+ Language.getString("KEYWORD_DESCRIPTION") + "\\b|" + "\\b"
				+ Language.getString("KEYWORD_START") + "\\b|" + "\\b"
				+ Language.getString("KEYWORD_END") + "\\b|" + "\\b" + Language.getString("KEYWORD_SET") + "\\b|"
				+ "\\b" + Language.getString("KEYWORD_COMPLETED") + "\\b|"
				+ "\\b" + Language.getString("KEYWORD_UNCOMPLETED") + "\\b|"
				+ Language.getString("DATE_FORMAT_REGEX") + "\\b";
	}

	// @author a0118677
	protected TreeMap<KeywordType, String> mapKeywordsToParameters(
			String parameterString) {
		//String lowerCaseParameterString = parameterString.toLowerCase();
		ParameterTokenizer tokenizer = new ParameterTokenizer(
				parameterString, tokenizerDelimiterRegex);
		TreeMap<KeywordType, String> mappingOfKeywordsToParameters = parseTokens(tokenizer);
		return mappingOfKeywordsToParameters;
	}

	//@author a0118677r
	private TreeMap<KeywordType, String> parseTokens(
			ParameterTokenizer tokenizer) {
		TreeMap<KeywordType, String> mappingOfKeywordsToParameters = new TreeMap<KeywordType, String>();
		if (tokenizer.hasMoreTokens()) {
			String nextToken = tokenizer.nextToken();
			return parseTokens(nextToken, tokenizer,
					mappingOfKeywordsToParameters);
		} else {
			return mappingOfKeywordsToParameters;
		}
	}

	//@author a0118677r
	private TreeMap<KeywordType, String> parseTokens(String token,
			ParameterTokenizer tokenizer,
			TreeMap<KeywordType, String> mappingOfKeywordsToParameters) {
		String nextToken = null;
		if (tokenizer.hasMoreTokens()) {
			nextToken = tokenizer.nextToken();
		}

		if (nextToken != null && mappingOfStringsToKeywords.containsKey(token)) {
			KeywordType keywordType = mappingOfStringsToKeywords.get(token);
			String keywordParameter = nextToken;

			switch (keywordType) {
			case START:
			case END:
				String checkDateValidity = Utilities.getDateFormat(keywordParameter);
				if (!checkDateValidity.isEmpty()) {
					mappingOfKeywordsToParameters.put(keywordType,
							keywordParameter);
					return returnDirectlyOrMakeRecursiveCall(tokenizer, mappingOfKeywordsToParameters);
				}
				break;
			case SET:
				if(keywordParameter.toLowerCase().equals(Language.getString("KEYWORD_COMPLETED")) || keywordParameter.toLowerCase().equals(Language.getString("KEYWORD_UNCOMPLETED"))){
					mappingOfKeywordsToParameters.put(keywordType, keywordParameter);
					return returnDirectlyOrMakeRecursiveCall(tokenizer, mappingOfKeywordsToParameters);
				}
				break;
			case DESCRIPTION:
				if (!mappingOfKeywordsToParameters.containsKey(keywordType)) {
					mappingOfKeywordsToParameters.put(keywordType,
							keywordParameter);
					return returnDirectlyOrMakeRecursiveCall(tokenizer, mappingOfKeywordsToParameters);
				}
				break;
			default:
				throw new RuntimeException("Unhandled KeywordType "
						+ keywordType);
			}
		}

		if (!mappingOfKeywordsToParameters.containsKey(KeywordType.DESCRIPTION)) {
			mappingOfKeywordsToParameters.put(KeywordType.DESCRIPTION, token);
		} else {
			String description = mappingOfKeywordsToParameters
					.get(KeywordType.DESCRIPTION);
			description += token;
			mappingOfKeywordsToParameters.put(KeywordType.DESCRIPTION,
					description);
		}
		if (nextToken != null) {
			return parseTokens(nextToken, tokenizer,
					mappingOfKeywordsToParameters);
		} else {
			return mappingOfKeywordsToParameters;
		}
	}
	
	//@author a0118677r
	private TreeMap<KeywordType, String> returnDirectlyOrMakeRecursiveCall(ParameterTokenizer tokenizer, TreeMap<KeywordType, String> mappingOfKeywordsToParameters) {
		if (tokenizer.hasMoreTokens()) {
			String nextToken = tokenizer.nextToken();
			return parseTokens(nextToken, tokenizer,
					mappingOfKeywordsToParameters);
		} else {
			return mappingOfKeywordsToParameters;
		}
	}
}
